package com.rookie.im.learn.io.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class NioServer {
    public static void main(String[] args) throws IOException {
        // 1. 创建服务通道
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        // 绑定端口
        serverChannel.socket().bind(new InetSocketAddress(9000));
        // 设置非阻塞
        serverChannel.configureBlocking(false);
        // 2. 创建多路复用器
        Selector selector = Selector.open();
        // 服务通道注册连接事件
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("服务启动");
        while (true) {
            // 等待注册事件
            selector.select();
            // 遍历事件
            Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
            while (keyIterator.hasNext()) {
                SelectionKey key = keyIterator.next();
                // 连接事件
                if (key.isAcceptable()) {
                    // 获取事件对象通道(服务通道)
                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                    // 从服务通道获取客户端通道
                    SocketChannel socketChannel = channel.accept();
                    // 设置非阻塞
                    socketChannel.configureBlocking(false);
                    // 注册读取事件
                    socketChannel.register(selector, SelectionKey.OP_READ);
                    System.out.println("客户端连接");

                }
                // 读取事件
                else if (key.isReadable()) {
                    SocketChannel channel = (SocketChannel) key.channel();
                    // 创建缓存
                    ByteBuffer buffer = ByteBuffer.allocate(128);
                    // 读取数据
                    int n = channel.read(buffer);
                    StringBuilder builder = new StringBuilder();
                    while (n > 0) {
                        builder.append(new String(buffer.array()));
                        buffer.clear();
                        n = channel.read(buffer);
                    }
                    System.out.println("客户端信息: " + builder.toString());

                }
                // 清除事件
                keyIterator.remove();
            }
        }
    }
}